

<!DOCTYPE html>
<html lang="zh-CN" data-default-color-scheme=auto>



<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/img/fluid.png">
  <link rel="icon" href="/img/fluid.png">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="author" content="叶飞">
  <meta name="keywords" content="">
  
    <meta name="description" content="HTTP基本概念  1 HTTP是什么 HTTP 是超文本传输协议，也就是HyperText Transfer Protocol。  2 HHTP详细详解 HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据 的「约定和规范」。   协议  对参与者（两个及以上）的行为约定和规范。 HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立">
<meta property="og:type" content="article">
<meta property="og:title" content="HTTP常见面试题">
<meta property="og:url" content="http://example.com/2022/04/02/HTTP%E5%B8%B8%E8%A7%81%E9%9D%A2%E8%AF%95%E9%A2%98/index.html">
<meta property="og:site_name" content="博客">
<meta property="og:description" content="HTTP基本概念  1 HTTP是什么 HTTP 是超文本传输协议，也就是HyperText Transfer Protocol。  2 HHTP详细详解 HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据 的「约定和规范」。   协议  对参与者（两个及以上）的行为约定和规范。 HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/v1.jpg">
<meta property="og:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/1.jpg">
<meta property="og:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/2.jpg">
<meta property="og:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/3.jpg">
<meta property="og:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/5.jpg">
<meta property="og:image" content="http://example.com/img/HTTP面试题/6.jpg">
<meta property="og:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/7.jpg">
<meta property="og:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/8.jpg">
<meta property="og:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/9.jpg">
<meta property="og:image" content="http://example.com/2022/04/02/HTTP%E5%B8%B8%E8%A7%81%E9%9D%A2%E8%AF%95%E9%A2%98/10.jpg">
<meta property="og:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/11.jpg">
<meta property="article:published_time" content="2022-04-02T06:57:14.000Z">
<meta property="article:modified_time" content="2022-04-02T07:52:26.251Z">
<meta property="article:author" content="叶飞">
<meta property="article:tag" content="面试">
<meta property="article:tag" content="HTTP">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="http://example.com/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/v1.jpg">
  
  
  
  <title>HTTP常见面试题 - 博客</title>

  <link  rel="stylesheet" href="https://lib.baomitu.com/twitter-bootstrap/4.6.1/css/bootstrap.min.css" />



  <link  rel="stylesheet" href="https://lib.baomitu.com/github-markdown-css/4.0.0/github-markdown.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/hint.css/2.7.0/hint.min.css" />

  <link  rel="stylesheet" href="https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.css" />



<!-- 主题依赖的图标库，不要自行修改 -->
<!-- Do not modify the link that theme dependent icons -->

<link rel="stylesheet" href="//at.alicdn.com/t/font_1749284_hj8rtnfg7um.css">



<link rel="stylesheet" href="//at.alicdn.com/t/font_1736178_lbnruvf0jn.css">


<link  rel="stylesheet" href="/css/main.css" />


  <link id="highlight-css" rel="stylesheet" href="/css/highlight.css" />
  
    <link id="highlight-css-dark" rel="stylesheet" href="/css/highlight-dark.css" />
  




  <script id="fluid-configs">
    var Fluid = window.Fluid || {};
    Fluid.ctx = Object.assign({}, Fluid.ctx)
    var CONFIG = {"hostname":"example.com","root":"/","version":"1.9.2","typing":{"enable":true,"typeSpeed":70,"cursorChar":"_","loop":false,"scope":[]},"anchorjs":{"enable":true,"element":"h1,h2,h3,h4,h5,h6","placement":"left","visible":"hover","icon":""},"progressbar":{"enable":true,"height_px":3,"color":"#29d","options":{"showSpinner":false,"trickleSpeed":100}},"code_language":{"enable":true,"default":"TEXT"},"copy_btn":true,"image_caption":{"enable":true},"image_zoom":{"enable":true,"img_url_replace":["",""]},"toc":{"enable":true,"placement":"right","headingSelector":"h1,h2,h3,h4,h5,h6","collapseDepth":0},"lazyload":{"enable":true,"loading_img":"/img/loading.gif","onlypost":false,"offset_factor":2},"web_analytics":{"enable":false,"follow_dnt":true,"baidu":null,"google":null,"gtag":null,"tencent":{"sid":null,"cid":null},"woyaola":null,"cnzz":null,"leancloud":{"app_id":null,"app_key":null,"server_url":null,"path":"window.location.pathname","ignore_local":false}},"search_path":"/local-search.xml"};

    if (CONFIG.web_analytics.follow_dnt) {
      var dntVal = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
      Fluid.ctx.dnt = dntVal && (dntVal.startsWith('1') || dntVal.startsWith('yes') || dntVal.startsWith('on'));
    }
  </script>
  <script  src="/js/utils.js" ></script>
  <script  src="/js/color-schema.js" ></script>
  


  
<meta name="generator" content="Hexo 6.2.0"></head>


<body>
  

  <header>
    

<div class="header-inner" style="height: 70vh;">
  <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand" href="/">
      <strong>No Tomorrow</strong>
    </a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/">
                <i class="iconfont icon-home-fill"></i>
                首页
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/archives/">
                <i class="iconfont icon-archive-fill"></i>
                归档
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/categories/">
                <i class="iconfont icon-category-fill"></i>
                分类
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/tags/">
                <i class="iconfont icon-tags-fill"></i>
                标签
              </a>
            </li>
          
        
          
          
          
          
            <li class="nav-item">
              <a class="nav-link" href="/about/">
                <i class="iconfont icon-user-fill"></i>
                关于
              </a>
            </li>
          
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" target="_self" href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
              &nbsp;<i class="iconfont icon-search"></i>&nbsp;
            </a>
          </li>
          
        
        
          <li class="nav-item" id="color-toggle-btn">
            <a class="nav-link" target="_self" href="javascript:;" aria-label="Color Toggle">&nbsp;<i
                class="iconfont icon-dark" id="color-toggle-icon"></i>&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

  

<div id="banner" class="banner" parallax=true
     style="background: url('/img/default.png') no-repeat center center; background-size: cover;">
  <div class="full-bg-img">
    <div class="mask flex-center" style="background-color: rgba(0, 0, 0, 0.3)">
      <div class="banner-text text-center fade-in-up">
        <div class="h2">
          
            <span id="subtitle" data-typed-text="HTTP常见面试题"></span>
          
        </div>

        
          
  <div class="mt-3">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-author" aria-hidden="true"></i>
        叶飞
      </span>
    
    
      <span class="post-meta">
        <i class="iconfont icon-date-fill" aria-hidden="true"></i>
        <time datetime="2022-04-02 14:57" pubdate>
          星期六, 四月 2日 2022, 2:57 下午
        </time>
      </span>
    
  </div>

  <div class="mt-1">
    
      <span class="post-meta mr-2">
        <i class="iconfont icon-chart"></i>
        
          <!-- compatible with older versions-->
          6.5k 字
        
      </span>
    

    
      <span class="post-meta mr-2">
        <i class="iconfont icon-clock-fill"></i>
        
        
        
          <!-- compatible with older versions-->
          55 分钟
        
      </span>
    

    
    
      
        <span id="leancloud-page-views-container" class="post-meta" style="display: none">
          <i class="iconfont icon-eye" aria-hidden="true"></i>
          <span id="leancloud-page-views"></span> 次
        </span>
        
      
    
  </div>


        
      </div>

      
    </div>
  </div>
</div>

</div>

  </header>

  <main>
    
      

<div class="container-fluid nopadding-x">
  <div class="row nomargin-x">
    <div class="side-col d-none d-lg-block col-lg-2">
      

    </div>

    <div class="col-lg-8 nopadding-x-md">
      <div class="container nopadding-x-md" id="board-ctn">
        <div id="board">
          <article class="post-content mx-auto">
            <!-- SEO header -->
            <h1 style="display: none">HTTP常见面试题</h1>
            
            
              <div class="markdown-body">
                
                <p><img src="/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/v1.jpg" srcset="/img/loading.gif" lazyload alt="亮白风格-图解网络-小林coding-v2"></p>
<h1 id="http基本概念"><a class="markdownIt-Anchor" href="#http基本概念"></a> HTTP基本概念</h1>
<h2 id="1-http是什么"><a class="markdownIt-Anchor" href="#1-http是什么"></a> 1 HTTP是什么</h2>
<p>HTTP 是超文本传输协议，也就是<strong>H</strong>yperText <strong>T</strong>ransfer <strong>P</strong>rotocol。</p>
<h2 id="2-hhtp详细详解"><a class="markdownIt-Anchor" href="#2-hhtp详细详解"></a> 2 HHTP详细详解</h2>
<p><strong>HTTP 是一个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据</strong><br>
<strong>的「约定和规范」。</strong></p>
<p><img src="/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/1.jpg" srcset="/img/loading.gif" lazyload alt="1"></p>
<ul>
<li>协议</li>
</ul>
<p>对参与者（两个及以上）的行为约定和规范。</p>
<p>HTTP 是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信<br>
的规范（两个以上的参与者），以及相关的各种控制和错误处理方式（行为约定和规范）。</p>
<ul>
<li>传输</li>
</ul>
<p>`HTTP 是一个在计算机世界里专门用来在<strong>两点之间</strong>传输数据的约定和规范</p>
<ul>
<li>超文本</li>
</ul>
<p>理解「超文本」，它就是超越了普通文本的文本，它是文字、图片、视频等的混合体，最关键有超<br>
链接，能从一个超文本跳转到另外一个超文本。</p>
<h2 id="3-那http-是用于从互联网服务器传输超文本到本地浏览器的协议-这种说法正确吗"><a class="markdownIt-Anchor" href="#3-那http-是用于从互联网服务器传输超文本到本地浏览器的协议-这种说法正确吗"></a> 3 那「HTTP 是用于从互联网服务器传输超文本到本地浏览器的协议 ，这种说法正确吗？</h2>
<p>这种说法是不正确的。因为也可以是**「服务器&lt; – &gt;服务器」<strong>，所以采用</strong>两点之间**的描述会更准确。</p>
<h2 id="4-http常见状态码"><a class="markdownIt-Anchor" href="#4-http常见状态码"></a> 4 HTTP常见状态码</h2>
<p><img src="/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/2.jpg" srcset="/img/loading.gif" lazyload alt="2"></p>
<h3 id="11xx"><a class="markdownIt-Anchor" href="#11xx"></a> （1）1xx</h3>
<p>​	<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mstyle mathcolor="red"><mrow><mn>1</mn><mi>x</mi><mi>x</mi></mrow></mstyle></mrow><annotation encoding="application/x-tex">\color{red}{1xx}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord" style="color:red;"><span class="mord" style="color:red;">1</span><span class="mord mathdefault" style="color:red;">x</span><span class="mord mathdefault" style="color:red;">x</span></span></span></span></span> 类状态码属于<strong>提示信息</strong>，是协议处理中的一种中间状态，实际用到的比较少。</p>
<h3 id="22xx"><a class="markdownIt-Anchor" href="#22xx"></a> （2）2xx</h3>
<p>​	<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mstyle mathcolor="red"><mrow><mn>2</mn><mi>x</mi><mi>x</mi></mrow></mstyle></mrow><annotation encoding="application/x-tex">\color{red}{2xx}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord" style="color:red;"><span class="mord" style="color:red;">2</span><span class="mord mathdefault" style="color:red;">x</span><span class="mord mathdefault" style="color:red;">x</span></span></span></span></span>状态码表示服务器<strong>成功处理</strong>了客户端的请求，也是我们最愿意看到的状态。</p>
<ul>
<li><strong>200 OK</strong> : 一切正常。若是是非HEAD请求，响应头会有body数据</li>
<li><strong>204 No Content</strong>： 响应头没有body数据</li>
<li><strong>206 Partial Content</strong>:应用于 HTTP 分块下载或断点续传，表示响应返回的 body 数据并不是资源<br>
的全部，而是其中的一部分，也是服务器处理成功的状态。</li>
</ul>
<h3 id="33xx"><a class="markdownIt-Anchor" href="#33xx"></a> （3）3xx</h3>
<p>​	<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mstyle mathcolor="red"><mrow><mn>3</mn><mi>x</mi><mi>x</mi></mrow></mstyle></mrow><annotation encoding="application/x-tex">\color{red}{3xx}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord" style="color:red;"><span class="mord" style="color:red;">3</span><span class="mord mathdefault" style="color:red;">x</span><span class="mord mathdefault" style="color:red;">x</span></span></span></span></span> 表示客户端请求的资源发送了变动  重定向。</p>
<ul>
<li>3301 Moved Permanently</li>
<li>302 Found ：临时重定向</li>
<li>304 Not Modified： 不具有跳转的含义，表示资源未修改，重定向已存在的缓冲文件，也称缓存重定<br>
向，用于缓存控制。</li>
</ul>
<h3 id="44xx"><a class="markdownIt-Anchor" href="#44xx"></a> （4）4xx</h3>
<p>​	<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mstyle mathcolor="red"><mrow><mn>4</mn><mi>x</mi><mi>x</mi></mrow></mstyle></mrow><annotation encoding="application/x-tex">\color{red}{4xx}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord" style="color:red;"><span class="mord" style="color:red;">4</span><span class="mord mathdefault" style="color:red;">x</span><span class="mord mathdefault" style="color:red;">x</span></span></span></span></span> 表示客户端发送的报文有误，服务器无法处理，也就是错误码的含义</p>
<ul>
<li>400 Bad Request  表示客户端请求的报文有错误，但只是个笼统的错误。</li>
<li>403 Forbidden      表示服务器禁止访问资源，并不是客户端的请求出错</li>
<li>404 Not Found  表示请求的资源在服务器上不存在或未找到，所以无法提供给客户端。</li>
</ul>
<h3 id="55xx"><a class="markdownIt-Anchor" href="#55xx"></a> （5）5xx</h3>
<p>​	<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mstyle mathcolor="red"><mrow><mn>5</mn><mi>x</mi><mi>x</mi></mrow></mstyle></mrow><annotation encoding="application/x-tex">\color{red}{5xx}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord" style="color:red;"><span class="mord" style="color:red;">5</span><span class="mord mathdefault" style="color:red;">x</span><span class="mord mathdefault" style="color:red;">x</span></span></span></span></span> 表示客户端请求报文正确，但是<strong>服务器</strong>处理时内部发生了错误</p>
<ul>
<li>500 Internal Server Error  笼统通用的错误码</li>
<li>501  Not Implemented  客户端请求的功能还不支持</li>
<li>502 Bad Gateway 服务器作为网关或代理时返回的错误码，表示服务器自身工作正常，访问后端服务器发生错误</li>
<li>503 Service Unavailable 服务器当前很忙，</li>
</ul>
<h2 id="5-http-常见字段有哪些"><a class="markdownIt-Anchor" href="#5-http-常见字段有哪些"></a> 5 http 常见字段有哪些？</h2>
<ul>
<li>Host字段：客户端发送请求时，用来指定服务器的域名。  Host: <a target="_blank" rel="noopener" href="http://www.A.com">www.A.com</a></li>
<li>Content-Length 字段：服务器在返回数据时，会有 Content-Length 字段，表明本次回应的数据长度。</li>
<li>Connection 字段：Connection 字段最常用于客户端要求服务器使用 TCP 持久连接，以便其他请求复用。</li>
<li>Content-Type 字段：用于服务器回应时，告诉客户端，本次数据是什么格式。
<ul>
<li>Content-Type: text/html; charset=utf-8</li>
<li>客户端请求的时候，可以使用 Accept 字段声明自己可以接受哪些数据格式。 <code>Accept: */*</code></li>
</ul>
</li>
<li>Content-Encoding 字段  说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式
<ul>
<li>Content-Encoding: gzip</li>
<li>客户端：<code>Accept-Encoding: gzip, deflate</code>    说明可接收的方法</li>
</ul>
</li>
</ul>
<h1 id="get和post"><a class="markdownIt-Anchor" href="#get和post"></a> Get和Post</h1>
<h2 id="1-说一下-get-和-post-的区别"><a class="markdownIt-Anchor" href="#1-说一下-get-和-post-的区别"></a> 1 说一下 GET 和 POST 的区别？</h2>
<ul>
<li>
<p><strong>Get</strong> 方法的含义是请求从服务器获取资源，这个资源可以是静态的文本、页面、图片视频等。</p>
</li>
<li>
<p><strong>POST</strong> 方法则是相反操作，它向 URI 指定的资源<strong>提交数据</strong>，数据就放在报文的 body 里</p>
</li>
</ul>
<h2 id="2-get-和-post-方法都是安全和幂等的吗"><a class="markdownIt-Anchor" href="#2-get-和-post-方法都是安全和幂等的吗"></a> 2 GET 和 POST 方法都是安全和幂等的吗？</h2>
<p>先说明下安全和幂等的概念：</p>
<ul>
<li>在 HTTP 协议里，所谓的「安全」是指请求方法不会「破坏」服务器上的资源。</li>
<li>所谓的「幂等」，意思是多次执行相同的操作，结果都是「相同」的。</li>
</ul>
<p>那么很明显 <strong>GET 方法就是安全且幂等的</strong>，因为它是「只读」操作，无论操作多少次，服务器上的数据<br>
都是安全的，且每次的结果都是相同的。</p>
<p>POST 因为是「新增或提交数据」的操作，会修改服务器上的资源，所以是<strong>不安全的</strong>，且多次提交数据<br>
就会创建多个资源，所以<strong>不是幂等</strong>的。</p>
<h1 id="http特性"><a class="markdownIt-Anchor" href="#http特性"></a> HTTP特性</h1>
<p><strong>Cookie</strong>: 通过在请求和响应报文中写入Ｃｏｏｋｉｅ信息控制客户端状态；由服务器生产，分配给客户端的一个身边标识数据</p>
<h2 id="1-http优点"><a class="markdownIt-Anchor" href="#1-http优点"></a> 1 HTTP优点</h2>
<ul>
<li>简单  基本格式是header+body，头部信息是简单的key-value简单文本的形式</li>
<li>灵活和易于扩充。HTTP各类请求方法、URL，状态码、头字段等没有固定死，支持自定义。[记得找一下头部字段的划分]</li>
<li>应用广泛和跨平台</li>
</ul>
<h2 id="2-http缺点"><a class="markdownIt-Anchor" href="#2-http缺点"></a> 2 Http缺点</h2>
<ul>
<li>无状态  双刃剑。
<ul>
<li>好处：服务器不记忆http状态，减小服务器负担</li>
<li>坏处：在完成有关联性的操作时比较麻烦，如需要身份信息的一些操作</li>
</ul>
</li>
<li>明文传输
<ul>
<li>好处：传输信息便于阅读</li>
<li>坏处：信息裸奔，安全风险</li>
</ul>
</li>
<li>不安全</li>
</ul>
<p>HTTP 比较严重的缺点就是不安全：</p>
<ul>
<li>通信使用明文（不加密），内容可能会被窃听。比如，账号信息容易泄漏，那你号没了。</li>
<li><strong>不验证通信方的身份</strong>，因此有可能遭遇伪装。比如，访问假的淘宝、拼多多，那你钱没了。</li>
<li><strong>无法证明报文的完整性</strong>，所以有可能已遭篡改。比如，网页上植入垃圾广告，视觉污染，眼没了。</li>
</ul>
<p>HTTPS的解决方案：引入SSL/TLS层</p>
<h2 id="3-http11性能"><a class="markdownIt-Anchor" href="#3-http11性能"></a> 3 HTTP/1.1性能</h2>
<p>基于<code>TCP/IP</code>，使用<code>请求-应答</code>的通信模式</p>
<h3 id="1长连接"><a class="markdownIt-Anchor" href="#1长连接"></a> （1）长连接</h3>
<p>早期 HTTP/1.0 性能上的一个很大的问题，那就是每发起一个请求，都要新建一次 TCP 连接（三次握手），而且是串行请求，做了无谓的 TCP 连接建立和断开，增加了通信开销。<br>
为了解决上述 TCP 连接问题，HTTP/1.1 提出了<code>长连接</code>的通信方式，也叫<strong>持久连接</strong>。这种方式的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销，减轻了服务器端的负载。</p>
<p>持久连接的特点是，只要任意一端没有明确提出断开连接，则保持 TCP 连接状态。</p>
<h3 id="2管道网络传输"><a class="markdownIt-Anchor" href="#2管道网络传输"></a> （2）管道网络传输</h3>
<p>HTTP/1.1 采用了长连接的方式，这使得**管道（pipeline）**网络传输成为了可能。</p>
<p>连续发送请求，服务端回应是按顺序回应。要是前面的回应特别慢，后面就会<br>
有许多请求排队等着。这称为「队头堵塞」。</p>
<h3 id="3队头阻塞"><a class="markdownIt-Anchor" href="#3队头阻塞"></a> （3）队头阻塞</h3>
<h1 id="https和http"><a class="markdownIt-Anchor" href="#https和http"></a> HTTPS和HTTP</h1>
<p>HTTPS:引入SLSL/TLS层</p>
<h2 id="1-区别"><a class="markdownIt-Anchor" href="#1-区别"></a> 1 区别</h2>
<ul>
<li>连接建立
<ul>
<li>HTTP  TCP三次握手</li>
<li>HTTPS TCP三次握手+SSL/TLS握手</li>
</ul>
</li>
<li>端口
<ul>
<li>HTTP 80</li>
<li>HTTPS  443</li>
</ul>
</li>
<li>安全性
<ul>
<li>HTTP 超文本传输协议  信息是明文，存在安全风险
<ul>
<li>窃听风险，比如通信链路上可以获取通信内容，用户号容易没。</li>
<li>篡改风险，比如强制植入垃圾广告，视觉污染，用户眼容易瞎。</li>
<li>冒充风险，比如冒充淘宝网站，用户钱容易没。</li>
</ul>
</li>
<li>HTTPs 再TCP和HTTP网络层之间加入SSL/TLS安全协议，报文加密传输
<ul>
<li>HTTPS 在 HTTP 与 TCP 层之间加入了 SSL/TLS 协议，可以很好的解决了上述的风险：</li>
<li>信息加密：交互信息无法被窃取，但你的号会因为「自身忘记」账号而没。</li>
<li>校验机制：无法篡改通信内容，篡改了就不能正常显示，但百度「竞价排名」依然可以搜索垃圾广告。</li>
<li>身份证书：证明淘宝是真的淘宝网，但你的钱还是会因为「剁手」而没。</li>
</ul>
</li>
</ul>
</li>
<li>证书
<ul>
<li>HTTPS 协议需要向 CA（证书权威机构）申请数字证书，来保证服务器的身份是可信的。</li>
</ul>
</li>
</ul>
<p><img src="/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/3.jpg" srcset="/img/loading.gif" lazyload alt="3"></p>
<h2 id="2-https-是如何解决上面的三个风险的"><a class="markdownIt-Anchor" href="#2-https-是如何解决上面的三个风险的"></a> 2 HTTPS 是如何解决上面的三个风险的</h2>
<p>HTTP 超文本传输协议  信息是明文，存在安全风险</p>
<ul>
<li>窃听风险，比如通信链路上可以获取通信内容，用户号容易没。</li>
<li>篡改风险，比如强制植入垃圾广告，视觉污染，用户眼容易瞎。</li>
<li>冒充风险，比如冒充淘宝网站，用户钱容易没。</li>
</ul>
<p>HTTPS策略</p>
<ul>
<li><strong>混合加密</strong>的方式实现信息的机密性，解决了窃听的风险。
<ul>
<li>对称加密和非对称加密混合
<ul>
<li>在通信建立前采用<strong>非对称加密</strong>的方式交换「会话秘钥」，后续就不再使用非对称加密。</li>
<li>在通信过程中全部使用<strong>对称加密</strong>的「会话秘钥」的方式加密明文数据。</li>
</ul>
</li>
<li>原因：
<ul>
<li>对称加密只使用一个密钥，运算速度快，密钥必须保密，无法做到安全的密钥交换。</li>
<li>非对称加密使用两个密钥：公钥和私钥，公钥可以任意分发而私钥保密，解决了密钥交换问题但<strong>速度慢</strong>。</li>
</ul>
</li>
</ul>
</li>
<li><strong>摘要算法</strong>的方式来实现完整性，它能够为数据生成独一无二的<span class="katex"><span class="katex-mathml"><math><semantics><mrow><mstyle mathcolor="blue"><mtext mathvariant="bold">「指纹」</mtext></mstyle></mrow><annotation encoding="application/x-tex">\color{blue}\textbf{「指纹」}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68611em;vertical-align:0em;"></span><span class="mord text" style="color:blue;"><span class="mord textbf cjk_fallback" style="color:blue;">「指纹」</span></span></span></span></span>，指纹用于校验数据的完整性，解决了篡改的风险。</li>
</ul>
<p>![亮白风格-图解网络-小林coding-v2.0.pdf - Adobe Acrobat Pro DC](/img/HTTP面试题/亮白风格-图解网络-小林coding-v2.0.pdf - Adobe Acrobat Pro DC.jpg)</p>
<p>客户端在发送明文之前会通过摘要算法算出明文的「指纹」，发送的时候把「指纹 + 明文」一同加密成密文后，发送给服务器，服务器解密后，用相同的摘要算法算出发送过来的明文，通过比较客户端携带的「指纹」和当前算出的「指纹」做比较，若「指纹」相同，说明数据是完整的。</p>
<ul>
<li>将<strong>服务器公钥放入到数字证书中</strong>，解决了冒充的风险。</li>
</ul>
<p><code>客户端先向服务器端索要公钥，然后用公钥加密信息，服务器收到密文后，用自己的私钥解密。</code></p>
<p>所以这里就需要借助第三方权威机构 CA （数字证书认证机构），将服务器公钥放在数字证书（由数字证书认证机构颁发）中，只要证书是可信的，公钥就是可信的。</p>
<p><span class="katex-error" title="ParseError: KaTeX parse error: Got function &#039;\large&#039; with no arguments as argument to &#039;\textbf&#039; at position 8: \textbf\̲l̲a̲r̲g̲e̲\color{red}{验证过…">\textbf\large\color{red}{验证过程}</span></p>
<p><img src="/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/5.jpg" srcset="/img/loading.gif" lazyload alt="5"></p>
<h2 id="3-https-是如何建立连接的其间交互了什么"><a class="markdownIt-Anchor" href="#3-https-是如何建立连接的其间交互了什么"></a> 3 HTTPS 是如何建立连接的？其间交互了什么？</h2>
<h3 id="1ssltls-协议基本流程"><a class="markdownIt-Anchor" href="#1ssltls-协议基本流程"></a> （1）SSL/TLS 协议基本流程：</h3>
<ul>
<li>
<p>客户端向服务器索要并验证服务器的公钥。</p>
</li>
<li>
<p>双方协商生产「会话秘钥」。</p>
</li>
<li>
<p>双方采用「会话秘钥」进行加密通信。<br>
前两步也就是 SSL/TLS 的建立过程，也就是握手阶段。</p>
<p>SSL/TLS 的「握手阶段」涉及<strong>四次通信</strong>，可见下图：</p>
<img src="/img/HTTP面试题/6.jpg" srcset="/img/loading.gif" lazyload alt="6" style="zoom:150%;">
</li>
</ul>
<h3 id="2ssltls-协议建立的详细流程"><a class="markdownIt-Anchor" href="#2ssltls-协议建立的详细流程"></a> （2）SSL/TLS 协议建立的详细流程：</h3>
<ul>
<li>1 ClientHello
<ul>
<li>客户端发送的信息
<ul>
<li>客户端支持的<strong>SSL/TLS版本</strong></li>
<li>客户端的随机数（Client Randomness)，用于产生会话密钥</li>
<li>客户端支持的密码套件列表，如RSA加密算法</li>
</ul>
</li>
</ul>
</li>
<li>2 ServerHello
<ul>
<li>服务端响应信息：
<ul>
<li>确认SSL/TLS版本</li>
<li>服务器生产的随机数（ Server Random ），后面用于生产「会话秘钥」。</li>
<li>确认的密码套件列表，如 RSA 加密算法。</li>
<li>服务器的数字证书。</li>
</ul>
</li>
</ul>
</li>
<li>3 客户端回应
<ul>
<li>客户端收到服务器的回应之后，首先通过浏览器或者操作系统中的 <strong>CA 公钥</strong>，确认服务器的<strong>数字证书的</strong><br>
<strong>真实性。</strong></li>
<li>如果证书没有问题，客户端会从数字证书中取出服务器的公钥，然后使用它加密报文，向服务器发送如<br>
下信息：
<ul>
<li>一个随机数（ pre-master key ）。该随机数会被服务器公钥加密。</li>
<li>加密通信算法改变通知，表示随后的信息都将用「会话秘钥」加密通信。</li>
<li>客户端握手结束通知，表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数<br>
据做个摘要，用来供服务端校验。</li>
</ul>
</li>
<li>上面第一项的随机数是整个握手阶段的第三个随机数，这样服务器和客户端就同时有三个随机数，接着<br>
就用双方协商的加密算法，各自生成本次通信的「会话秘钥」。</li>
</ul>
</li>
<li>4 服务器的最后回应
<ul>
<li>服务器收到客户端的第三个随机数（ pre-master key ）之后，通过协商的加密算法，计算出本次通信的<br>
「会话秘钥」。然后，向客户端发生最后的信息：
<ul>
<li>加密通信算法改变通知，表示随后的信息都将用「会话秘钥」加密通信。</li>
<li>服务器握手结束通知，表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数<br>
据做个摘要，用来供客户端校验。</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="http11-http2-http3演变"><a class="markdownIt-Anchor" href="#http11-http2-http3演变"></a> HTTP/1.1、HTTP/2、HTTP/3演变</h1>
<h2 id="1-说说-http11-相比-http10-提高了什么性能"><a class="markdownIt-Anchor" href="#1-说说-http11-相比-http10-提高了什么性能"></a> 1 说说 HTTP/1.1 相比 HTTP/1.0 提高了什么性能？</h2>
<p>HTTP/1.1 相比 HTTP/1.0 性能上的改进：</p>
<ul>
<li>使用 TCP 长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。</li>
<li>支持管道（pipeline）网络传输，只要第一个请求发出去了，不必等其回来，就可以发第二个请求<br>
出去，可以减少整体的响应时间。</li>
</ul>
<p>但 HTTP/1.1 还是有性能瓶颈：</p>
<ul>
<li>请求 / 响应头部（Header）<strong>未经压缩</strong>就发送，首部信息越多延迟越大。只能压缩 Body 的部分；<br>
发送冗长的首部。每次互相发送相同的首部造成的浪费较多；</li>
<li>服务器是按请求的顺序响应的，如果服务器响应慢，会招致客户端一直请求不到数据，也就是队头阻塞；</li>
<li>没有请求优先级控制；</li>
<li>请求只能从客户端开始，服务器只能被动响应。</li>
</ul>
<h2 id="2-那上面的-http11-的性能瓶颈http2-做了什么优化"><a class="markdownIt-Anchor" href="#2-那上面的-http11-的性能瓶颈http2-做了什么优化"></a> 2 那上面的 HTTP/1.1 的性能瓶颈，HTTP/2 做了什么优化？</h2>
<p>HTTP/2 协议是基于 HTTPS 的，所以 HTTP/2 的安全性也是有保障的。</p>
<ul>
<li>
<p>头部压缩：HTTP/2 会压缩头（Header）如果你同时发出多个请求，他们的头是一样的或是相似的，那么，协议会<br>
帮你消除重复的部分。<br>
这就是所谓的 HPACK 算法：在客户端和服务器同时维护一张头信息表，所有字段都会存入这个表，<br>
生成一个索引号，以后就不发送同样字段了，只发送索引号，这样就提高速度了。</p>
</li>
<li>
<p>二进制格式：HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文，而是全面采用了二进制格式，头信息和数据体都是<br>
二进制，并且统称为帧（frame）：头信息帧和数据帧。  增加了数据传输的效率。</p>
<p><img src="/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/7.jpg" srcset="/img/loading.gif" lazyload alt="7"></p>
</li>
<li>
<p>数据流</p>
</li>
</ul>
<p>HTTP/2 的数据包<strong>不是按顺序</strong>发送的，同一个连接里面连续的数据包，可能属于不同的回应。因此，必<br>
<strong>须要对数据包做标记</strong>，指出它属于哪个回应。<br>
每个请求或回应的所有数据包，称为一个<strong>数据流（ Stream ）</strong>。每个数据流都标记着一个独一无二的编<br>
号，其中规定<strong>客户端发出的数据流编号为奇数</strong>， <strong>服务器发出的数据流编号为偶数</strong><br>
<strong>客户端还可以指定数据流的优先</strong>级。优先级高的请求，服务器就先响应该请求。</p>
<p><img src="/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/8.jpg" srcset="/img/loading.gif" lazyload alt="8"></p>
<ul>
<li>
<p>多路复用</p>
<p>HTTP/2 是可以在一个连接中并发多个请求或回应，而不用按照顺序一一对应。移除了 HTTP/1.1 中的串行请求，不需要排队等待，也就不会再出现「队头阻塞」问题，<strong>降低了延迟，大幅度提高了连接的利用率。</strong></p>
<p>举例来说，在一个 TCP 连接里，服务器收到了客户端 A 和 B 的两个请求，如果发现 A 处理过程非常耗<br>
时，于是就回应 A 请求已经处理好的部分，接着回应 B 请求，完成后，再回应 A 请求剩下的部分。</p>
</li>
</ul>
<h2 id="9"><a class="markdownIt-Anchor" href="#9"></a> <img src="/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/9.jpg" srcset="/img/loading.gif" lazyload alt="9"></h2>
<ul>
<li>服务器推送</li>
</ul>
<p>HTTP/2 还在一定程度上改善了传统的「请求 - 应答」工作模式，服务器不再是被动地响应，也可以<strong>主动</strong><br>
<strong>向客户端发送消息</strong>。</p>
<p>举例来说，在浏览器刚请求 HTML 的时候，就提前把可能会用到的 <strong>JS、CSS 文件等静态资源</strong>主动发给<br>
客户端，<strong>减少延时的等待</strong>，也就是服务器推送（Server Push，也叫 Cache Push）。</p>
<h2 id="3-http2-有哪些缺陷http3-做了哪些优化"><a class="markdownIt-Anchor" href="#3-http2-有哪些缺陷http3-做了哪些优化"></a> 3 HTTP/2 有哪些缺陷？HTTP/3 做了哪些优化？</h2>
<p>HTTP/2 主要的问题在于，多个 HTTP 请求在复用一个 TCP 连接，下层的 TCP 协议是不知道有多少个<br>
HTTP 请求的。所以一旦发生了丢包现象，就会触发 <strong>TCP 的重传机制</strong>，这样在一个 TCP 连接中的<strong>所有</strong><br>
<strong>的 HTTP 请求都必须等待这个丢了的包被重传回来</strong>。</p>
<ul>
<li>HTTP/1.1 中的管道（ pipeline）传输中如果有一个请求阻塞了，那么队列后请求也统统被阻塞住<br>
了</li>
<li>HTTP/2 多个请求复用一个TCP连接，一旦发生丢包，就会阻塞住所有的 HTTP 请求。</li>
</ul>
<p>这都是基于 TCP 传输层的问题，所以 <strong>HTTP/3 把 HTTP 下层的 TCP 协议改成了 UDP！</strong></p>
<p><img src="/2022/04/02/HTTP%E5%B8%B8%E8%A7%81%E9%9D%A2%E8%AF%95%E9%A2%98/10.jpg" srcset="/img/loading.gif" lazyload alt="10"></p>
<p>基于 UDP 的 <strong>QUIC</strong> 协议 可以实现类似 TCP 的<strong>可靠性传输。</strong></p>
<ul>
<li>QUIC 有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时，只会阻塞这个流，其他流不会受到影响。</li>
<li>TLS3 升级成了最新的 1.3 版本，头部压缩算法也升级成了 <strong>QPack</strong> 。</li>
<li>HTTPS 要建立一个连接，要花费 6 次交互，先是建立三次握手，然后是 TLS/1.3 的三次握手。QUIC 直接把以往的 TCP 和 TLS/1.3 的 6 次交互<strong>合并成了 3 次，减少了交互次数。</strong></li>
</ul>
<p><img src="/img/HTTP%E9%9D%A2%E8%AF%95%E9%A2%98/11.jpg" srcset="/img/loading.gif" lazyload alt="11"></p>
<p>所以， QUIC 是一个在 UDP 之上的<strong>伪 TCP + TLS + HTTP/2 的多路复用的协议</strong>。</p>

                
              </div>
            
            <hr/>
            <div>
              <div class="post-metas my-3">
  
    <div class="post-meta mr-3 d-flex align-items-center">
      <i class="iconfont icon-category"></i>
      

<span class="category-chains">
  
  
    
      <span class="category-chain">
        
  <a href="/categories/%E7%BD%91%E7%BB%9C/" class="category-chain-item">网络</a>
  
  

      </span>
    
  
</span>

    </div>
  
  
    <div class="post-meta">
      <i class="iconfont icon-tags"></i>
      
        <a href="/tags/%E9%9D%A2%E8%AF%95/">#面试</a>
      
        <a href="/tags/HTTP/">#HTTP</a>
      
    </div>
  
</div>


              
  

  <div class="license-box my-3">
    <div class="license-title">
      <div>HTTP常见面试题</div>
      <div>http://example.com/2022/04/02/HTTP常见面试题/</div>
    </div>
    <div class="license-meta">
      
        <div class="license-meta-item">
          <div>作者</div>
          <div>叶飞</div>
        </div>
      
      
        <div class="license-meta-item license-meta-date">
          <div>发布于</div>
          <div>2022年4月2日</div>
        </div>
      
      
      <div class="license-meta-item">
        <div>许可协议</div>
        <div>
          
            
            
              <a target="_blank" href="https://creativecommons.org/licenses/by/4.0/">
              <span class="hint--top hint--rounded" aria-label="BY - 署名">
                <i class="iconfont icon-by"></i>
              </span>
              </a>
            
          
        </div>
      </div>
    </div>
    <div class="license-icon iconfont"></div>
  </div>



              
                <div class="post-prevnext my-3">
                  <article class="post-prev col-6">
                    
                    
                      <a href="/2022/04/02/TCP%E6%8F%A1%E6%89%8B/" title="TCP握手">
                        <i class="iconfont icon-arrowleft"></i>
                        <span class="hidden-mobile">TCP握手</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </article>
                  <article class="post-next col-6">
                    
                    
                      <a href="/2022/04/02/Docker%E4%BB%8E0%E6%9E%84%E5%BB%BAC-%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/" title="Docker从0构建C++开发环境">
                        <span class="hidden-mobile">Docker从0构建C++开发环境</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="iconfont icon-arrowright"></i>
                      </a>
                    
                  </article>
                </div>
              
            </div>

            
          </article>
        </div>
      </div>
    </div>

    <div class="side-col d-none d-lg-block col-lg-2">
      
  <aside class="sidebar" style="margin-left: -1rem">
    <div id="toc">
  <p class="toc-header"><i class="iconfont icon-list"></i>&nbsp;目录</p>
  <div class="toc-body" id="toc-body"></div>
</div>



  </aside>


    </div>
  </div>
</div>





  



  



  



  



  


  
  









    

    
      <a id="scroll-top-button" aria-label="TOP" href="#" role="button">
        <i class="iconfont icon-arrowup" aria-hidden="true"></i>
      </a>
    

    
      <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v" for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>

    

    
  </main>

  <footer>
    <div class="footer-inner">
  
    <div class="footer-content">
       <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><span>Hexo</span></a> <i class="iconfont icon-love"></i> <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"><span>Fluid</span></a> 
    </div>
  
  
  
  
</div>

  </footer>

  <!-- Scripts -->
  
  <script  src="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.js" ></script>
  <link  rel="stylesheet" href="https://lib.baomitu.com/nprogress/0.2.0/nprogress.min.css" />

  <script>
    NProgress.configure({"showSpinner":false,"trickleSpeed":100})
    NProgress.start()
    window.addEventListener('load', function() {
      NProgress.done();
    })
  </script>


<script  src="https://lib.baomitu.com/jquery/3.6.0/jquery.min.js" ></script>
<script  src="https://lib.baomitu.com/twitter-bootstrap/4.6.1/js/bootstrap.min.js" ></script>
<script  src="/js/events.js" ></script>
<script  src="/js/plugins.js" ></script>


  <script  src="https://lib.baomitu.com/typed.js/2.0.12/typed.min.js" ></script>
  <script>
    (function (window, document) {
      var typing = Fluid.plugins.typing;
      var subtitle = document.getElementById('subtitle');
      if (!subtitle || !typing) {
        return;
      }
      var text = subtitle.getAttribute('data-typed-text');
      
        typing(text);
      
    })(window, document);
  </script>




  
    <script  src="/js/img-lazyload.js" ></script>
  




  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/tocbot/4.18.2/tocbot.min.js', function() {
    var toc = jQuery('#toc');
    if (toc.length === 0 || !window.tocbot) { return; }
    var boardCtn = jQuery('#board-ctn');
    var boardTop = boardCtn.offset().top;

    window.tocbot.init({
      tocSelector     : '#toc-body',
      contentSelector : '.markdown-body',
      headingSelector : CONFIG.toc.headingSelector || 'h1,h2,h3,h4,h5,h6',
      linkClass       : 'tocbot-link',
      activeLinkClass : 'tocbot-active-link',
      listClass       : 'tocbot-list',
      isCollapsedClass: 'tocbot-is-collapsed',
      collapsibleClass: 'tocbot-is-collapsible',
      collapseDepth   : CONFIG.toc.collapseDepth || 0,
      scrollSmooth    : true,
      headingsOffset  : -boardTop
    });
    if (toc.find('.toc-list-item').length > 0) {
      toc.css('visibility', 'visible');
    }
  });
</script>


  <script src=https://lib.baomitu.com/clipboard.js/2.0.10/clipboard.min.js></script>

  <script>Fluid.plugins.codeWidget();</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/anchor-js/4.3.1/anchor.min.js', function() {
    window.anchors.options = {
      placement: CONFIG.anchorjs.placement,
      visible  : CONFIG.anchorjs.visible
    };
    if (CONFIG.anchorjs.icon) {
      window.anchors.options.icon = CONFIG.anchorjs.icon;
    }
    var el = (CONFIG.anchorjs.element || 'h1,h2,h3,h4,h5,h6').split(',');
    var res = [];
    for (var item of el) {
      res.push('.markdown-body > ' + item.trim());
    }
    if (CONFIG.anchorjs.placement === 'left') {
      window.anchors.options.class = 'anchorjs-link-left';
    }
    window.anchors.add(res.join(', '));
  });
</script>


  
<script>
  Fluid.utils.createScript('https://lib.baomitu.com/fancybox/3.5.7/jquery.fancybox.min.js', function() {
    Fluid.plugins.fancyBox();
  });
</script>


  <script>Fluid.plugins.imageCaption();</script>

  
      <script>
        if (!window.MathJax) {
          window.MathJax = {
            tex    : {
              inlineMath: { '[+]': [['$', '$']] }
            },
            loader : {
              load: ['ui/lazy']
            },
            options: {
              renderActions: {
                insertedScript: [200, () => {
                  document.querySelectorAll('mjx-container').forEach(node => {
                    let target = node.parentNode;
                    if (target.nodeName.toLowerCase() === 'li') {
                      target.parentNode.classList.add('has-jax');
                    }
                  });
                }, '', false]
              }
            }
          };
        } else {
          MathJax.startup.document.state(0);
          MathJax.texReset();
          MathJax.typeset();
          MathJax.typesetPromise();
        }
      </script>
    

  <script  src="https://lib.baomitu.com/mathjax/3.2.1/es5/tex-mml-chtml.js" ></script>

  <script  src="/js/local-search.js" ></script>

  <script defer src="/js/leancloud.js" ></script>





<!-- 主题的启动项，将它保持在最底部 -->
<!-- the boot of the theme, keep it at the bottom -->
<script  src="/js/boot.js" ></script>


  

  <noscript>
    <div class="noscript-warning">博客在允许 JavaScript 运行的环境下浏览效果更佳</div>
  </noscript>
<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"log":false,"pluginJsPath":"lib/","pluginModelPath":"assets/","pluginRootPath":"live2dw/","tagMode":false});</script></body>
</html>
